Language Integrated Query (LINQ) as a precursor
Reaqtorの祖先は、2005年~2007年にさかのぼるLINQです。C#およびVisual Basic言語チームによって設計されたLINQの目的は、オブジェクト指向プログラミング言語と、インメモリコレクション、XMLドキュメント、リレーショナルデータベースなどの様々な問い合わせ可能なデータソースとの間の「インピーダンスミスマッチ」を解決することです。メモリ内コレクションへの問い合わせは、foreachループなどの言語構成を使用することで比較的容易ですが、リレーショナルデータベースなどの他のタイプのデータソースへの問い合わせは、SQLなどの他言語をコードに埋め込む必要があります。多くの場合、IntelliSense、ステートメント補完、型チェックなどの恩恵を受けられない文字列リテラルとして使用されます。
The grandfather of Reaqtor is LINQ, which dates back to 2005-2007. Designed by the C# and Visual Basic language teams, the goal of LINQ is to solve the “impedance mismatch” between object-oriented programming languages and a variety of queryable data sources, including in-memory collections, XML documents, relational databases, and more. While querying in-memory collections is relatively easy by using language constructs such as foreach loops, querying other types of data sources such as relational databases involves embedding foreign languages such as SQL into the code, often as string literals which don’t benefit from IntelliSense, statement completion, type checking, etc.
code:C#
var command = connection.CreateCommand("SELECT ProductName, UnitPrice FROM Products WHERE UnitPrice > 49.95");
var reader = command.ExecuteReader();
while (reader.Read())
{
// ...
}
既存のデータアクセス方法では、オブジェクト/リレーショナル(O/R)マッピング技術の必要性、foreachなどの言語構造とうまく統合できる列挙可能なシーケンスの概念と互換性のないプログラミングモデル、異なるソースからのデータを統合するために必要なさまざまなアプローチ(例:リレーショナルデータベースのデータとXMLドキュメントのデータの結合)など、さらに複雑な問題がありました。
Further complexity with existing data access methods includes the need for object/relational (O/R) mapping technologies, programming models that aren’t compatible with the notion of enumerable sequences which integrate well with language constructs such as foreach, and the different approaches needed to blend data from different sources together (e.g. joining between data in a relational database and data in an XML document).
これらの実現により、2004年のComega社の研究成果を基にしたLINQ(Language Integrated Query)が誕生しました。C# 3.0とVisual Basic 9では、HaskellやF#などの関数型プログラミング言語のクエリ内包と同様に、クエリ式の構文が言語に統合されました。
These realizations led to the creation of Language Integrated Query (LINQ) which itself was based on the Comega research effort in 2004. Both C# 3.0 and Visual Basic 9 received query expression syntax integrated into the language, much like query comprehensions in Haskell, F#, and other functional programming languages.
code:C#
var res = from p in ctx.GetTable<Product>("Products")
where p.UnitPrice > 49.95m
select new { Name = p.ProductName, Price = p.UnitPrice };
foreach (var p in res)
{
// ...
}
C# 3.0 および Visual Basic 9 では、クエリ式の構文(from x in xs ...)のほかに、ローカル変数の型推論(var)、無名型(new { x = 1 })、ラムダ式(x => x * 2)、拡張メソッドなど、関連するさまざまな言語機能が導入されました。クエリ式は、これらの新しい機能を含む、よりプリミティブな言語構造に変換されます。
"Besides query expression syntax (from x in xs ...), C# 3.0 and Visual Basic 9 introduced a variety of related language features, including local variable type inference (var), anonymous types (new { x = 1 }), lambda expressions (x => x * 2), extension methods, etc. Query expressions translate to more primitive language constructs, including these new ones:
code:C#
var res = ctx.GetTable<Product>("Products")
.Where(p => p.UnitPrice > 49.95m);
クエリ式は、IEnumerable<T> を実装したメモリ内のコレクション、または IQueryable<T> を実装した外部のデータソースに対して書くことができます。前者の場合、Where や Select などのクエリ演算子はイテレータ (yield return x) を使用して実装され、ステートマシンに支えられた遅延評価可能な列挙型シーケンスのオブジェクトグラフとしてメモリ内で実行されます。後者の場合、Where や Select などのクエリ演算子は、ユーザの意図全体を表す式ツリーを生成するために、ラムダ式のパラメータを式ツリーのデータ構造に引用します。列挙が開始されると(foreachなど)、この式木が基礎となるクエリプロバイダライブラリによって分析され、T-SQLなどのターゲット言語に翻訳されてクエリが実行されます。
Query expressions can be written against in-memory collections implementing IEnumerable<T> or external data sources implementing IQueryable<T>. In the former case, query operators such as Where and Select are implemented using iterators (yield return x) and execute in memory as an object graph of lazily evaluated enumerable sequences backed by state machines. In the latter case, query operators such as Where and Select quote their lambda expression parameters into expression tree data structures in order to produce an expression tree that represents the entire user intent. Upon triggering enumeration (e.g. using foreach), this expression tree is analyzed by the underlying query provider library, and translated to a target language such as T-SQL in order to execute the query.
C#、Visual Basic、またはF#から使用する場合、クエリ式は現在のReaqtorの主要なプログラミングモデルです。式ツリーは、クライアントとReaqtorサービスの間、およびReaqtor内の異なるマイクロサービス間で正規化およびシリアル化される基本的な表現として使用されます。
Query expressions are the primary programming model for Reaqtor today, when used from C#, Visual Basic, or F#. Expression trees are used as the underlying representation that gets normalized and serialized over the wire between clients and the Reaqtor service, as well as across different micro-services inside Reaqtor.